import java.util.Random;
import java.util.concurrent.*;

/**
 * CyclicBarrier是一个同步辅助类，它允许一组线程相互等待，直到达到某个公共的屏障点。在设计一组固定大小的线程的程序中，
 * 这些线程必须不时的相互等待，此时CyclicBarrier
 * 很有用，因为barrier在释放等待线程后可以重用，所以称它为循环的barrier
 * <p>
 * 需要所有的子任务都完成时，才执行任务，这时可以选择CyclicBarrier
 */
public class CyclicBarrierTest {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        executorService.submit(new Thread(new Runner(cyclicBarrier, "1")));
        executorService.submit(new Thread(new Runner(cyclicBarrier, "2")));
        executorService.submit(new Thread(new Runner(cyclicBarrier, "3")));
        System.out.println(" end = ");
        executorService.shutdown();
    }
}
class Runner implements Runnable {
    // 一个同步辅助类，他允许一组线程相互等待，知道达到某个公共屏点
    private CyclicBarrier cyclicBarrier;
    private String name;
    public Runner(CyclicBarrier cyclicBarrier, String name) {
        super();
        this.cyclicBarrier = cyclicBarrier;
        this.name = name;
    }
    public void run() {
        try {
            Thread.sleep(1000 * (new Random()).nextInt(8));
            System.out.println("name = " + name);
            try {
                // barrier的await方法，在所有参与者都已经在此barrier上调用await方法之前将一直等待
                cyclicBarrier.await();
                // 设置的等待时间。如果等待了1秒，最后一个线程还没有就位，则自己继续运行，但是回到之Barrier被i奥基为一个已经破坏的Barrier
                // cyclicBarrier.await(1, TimeUnit.SECONDS);
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("起跑 = ");
    }
}

